﻿using AbpApplication.Expand;
using AbpEntityFrameworkcore.DbContext;
using AbpToDomain.EntityInfo;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using NStandard;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using AbpApplication.InPut;
using Application.Expand;
using AbpApplication.Dto;
using AbpToDomain.View;
using Volo.Abp.Users;
using AbpToDomain.Repository;
using System.Reflection.Emit;

namespace AbpApplication.AppServices
{
    ///<inheritdoc/>
    public class BaseService : ApplicationService, IBaseService
    {

        private readonly IRepository<Box> Box_res;
        private readonly IRepository<BoxGrid> BoxGrid_res;
        private readonly IRepository<NeetOutMaterial> NeetOutMaterial_res;
        private readonly IRepository<TaskOrder> TaskOrder_res;
        private readonly IRepository<Warehouse> Warehouse_res;
        private readonly IRepository<WarehouseLine> WarehouseLine_res;
        private readonly IRepository<MaterialBase> MaterialBase_res;
        private readonly IRepository<Inlethouse> Inlethouse_res;
        private readonly IRepository<InlethouseLine> Inlethouseline_res;
        private readonly IRepository<lognote> LogNote_res;
        private readonly IRepository<MaterialProperty> MaterialProperty_res;
        private readonly IRepository<BoxPosition> BoxPosition_res;
        private readonly IRepository<BoxType> BoxType_res;
        private readonly IRepository<PutInOrder> PutInOrder_res;
        private readonly IRepository<PutOutOrder> PutOutOrder_res;
        private readonly ICurrentUser User;

        private readonly MyDbContext context;
        private readonly ILoginHelper loginHelper;
        public BaseService(
            IRepository<Box> box_res,
            IRepository<BoxGrid> boxGrid_res,
            IRepository<Warehouse> warehouse_res,
            IRepository<WarehouseLine> warehouseLine_res,
            IRepository<MaterialBase> materialBase_res,
            MyDbContext context,
            IRepository<NeetOutMaterial> neetOutMaterial_res,
            IRepository<Inlethouse> inlethouse_res,
            IRepository<InlethouseLine> inlethouseline_res,
            IRepository<TaskOrder> taskOrder_res,
            ILoginHelper loginHelper,
            IRepository<lognote> logNote_res,
            IRepository<MaterialProperty> materialProperty_res,
            IRepository<BoxPosition> boxPosition_res,
            IRepository<BoxType> binType_res,
            IRepository<PutInOrder> putInOrder_res,
            IRepository<PutOutOrder> putOutOrder_res,
            ICurrentUser user)
        {
            Box_res = box_res;
            BoxGrid_res = boxGrid_res;
            Warehouse_res = warehouse_res;
            WarehouseLine_res = warehouseLine_res;
            MaterialBase_res = materialBase_res;
            this.context = context;
            NeetOutMaterial_res = neetOutMaterial_res;
            Inlethouse_res = inlethouse_res;
            Inlethouseline_res = inlethouseline_res;
            TaskOrder_res = taskOrder_res;
            this.loginHelper = loginHelper;
            LogNote_res = logNote_res;
            MaterialProperty_res = materialProperty_res;
            BoxPosition_res = boxPosition_res;
            BoxType_res = binType_res;
            PutInOrder_res = putInOrder_res;
            PutOutOrder_res = putOutOrder_res;
            User = user;
        }

        
        public async Task<ApiResponse> CreateMaterialBase(InPut_BaseService7 inPut)//新料入库
        {
            try
            {
                Box box=  await context.boxs.Include(x => x.BoxGrids).ThenInclude(x => x.BoxPositions).ThenInclude(x => x.MaterialBase).FirstOrDefaultAsync(x => x.BoxCode .Contains( inPut.BoxPositionCode));
                if(box == null)
                {
                    return new ApiResponse($"未查询到的料盒", false, null);
                }
              BoxType boxType=    await context.BoxTypes.FirstOrDefaultAsync(x=>x.BoxType_Name == inPut.BoxTypeName);
                if (boxType == null)
                {
                    return new ApiResponse("未查询到料盒类型", false, null);
                }
                foreach (var boxGrid in box.BoxGrids)
                {
                    foreach (var boxposition in boxGrid.BoxPositions)
                    {
                        if(boxposition.MaterialBase!=null&& boxposition.MaterialBase.MaterialName != inPut.MaterialName)
                        {
                            return new ApiResponse($"{inPut.BoxPositionCode}已经存在其他类型的蔬菜", false, null);
                        }
                    }
                }

                BoxPosition boxPosition = await BoxPosition_res.FirstOrDefaultAsync(x => x.BoxPositionCode.Contains(inPut.BoxPositionCode) && x.MaterialBase == null);
                if (boxPosition == null)
                {
                    return new ApiResponse($"{inPut.BoxPositionCode}已无空位", false, null);
                }
                //update Box
                box.BoxType = boxType;
                box.UpdateTime = DateTime.Now;
                await Box_res.UpdateAsync(box);

                //create material
                MaterialBase materialBase = new MaterialBase();
                materialBase.MaterialName = inPut.MaterialName;
                materialBase.Poundage = inPut.Poundage;
                materialBase.CreatedDate = DateTime.Now;
                materialBase.PeoPle = User.UserName;
                materialBase.BoxPosition = boxPosition;
                materialBase.MaterialuniqueCode = ExtendRandom.CreateRandom();
                await MaterialBase_res.InsertAsync(materialBase);
                await LogNote_res.InsertAsync(new lognote()
                {
                    BoxCode = box.BoxCode,
                    Note = $"{materialBase.MaterialName} 入库+重量:{materialBase.Poundage}+料盒{boxPosition.BoxPositionCode}",
                    Type = "入库",
                    DateTime=DateTime.Now,
                    User = User.UserName
                });
                return new ApiResponse("加入料盒成功", true, null);

            }
            catch (Exception ex)
            {

                loginHelper.LoginAsync(inPut, "CreateMaterialBase");
                return new ApiResponse("ERROR-CreateMaterialBase", false, null);
            }

        }
        public async Task<ApiResponse> CreateLog(InPut_BaseService15 InPut)//添加日志
        {
            lognote lognote = new lognote();
            lognote.DateTime = DateTime.Now;
            lognote.User = InPut.User;
            lognote.Type = InPut.Type;
            lognote.Note = InPut.Note;
            await LogNote_res.InsertAsync(lognote);
            return new ApiResponse("添加成功", true, null);
        }
        public async Task<ApiResponse> Update_Box(InPut_BaseService2 input)//更改箱盒
        {
            try
            {
                //var boxs = await Box_res.WithDetailsAsync();
                //Box box=await  boxs.FirstOrDefaultAsync(x=>x.BoxCode == input.BoxCode);
                //if (box==null) return new ApiResponse("未查询到料盒", false, null);
                //foreach (var item in box.BoxGrids)
                //{
                //    if (item.materialBase!=null)
                //    {
                //        return new ApiResponse("料盒中有物料不允许修改", false, null);
                //    }
                //}
                //box.BoxCode = input.BoxCode;
                //box.BoxGrids.Clear();
                //await Box_res.UpdateAsync(box);
                //List<BoxGrid> boxGrids = new List<BoxGrid>();
                //for (int i = 0; i < input.BoxGridQuantity; i++)
                //{
                //    BoxGrid boxGrid = new BoxGrid();
                //    string BoxGridCode = $"{box.BoxCode}_{(i + 1).ToString("D2")}";
                //    boxGrid = boxGrid.AddBoxGrid(i+ 1, BoxGridCode, box, 0);
                //    boxGrids.Add(boxGrid);
                //}
                //await BoxGrid_res.InsertManyAsync(boxGrids);
                //box.BoxGrids.AddRange(boxGrids);
                //box.BoxGridQuantity = (int)input.BoxGridQuantity;
                //await Box_res.UpdateAsync(box);
                return new ApiResponse("更新成功", true, null);
                //var boxs = await Box_res.WithDetailsAsync();
                //foreach (var boxcode in input.BoxCode)
                //{
                //    Box box = boxs.FirstOrDefault(x => x.BoxCode == boxcode);
                //    if (box == null)
                //    {
                //        return new ApiResponse("未查询到", false, null);
                //    }                
                //    box.BoxGrids .Clear();
                //    await Box_res.UpdateAsync(box);
                //    await UnitOfWorkManager.Current.SaveChangesAsync();

                //    List<BoxGrid> boxGrids = new List<BoxGrid>();
                //    for (int i = 0; i < input.BoxGridQuantity; i++)
                //    {
                //        BoxGrid boxGrid = new BoxGrid();
                //        string BoxGridCode = $"{box.BoxCode}_{(i + 1).ToString("D2")}";
                //        boxGrid = boxGrid.AddBoxGrid(i + 1, BoxGridCode, box);              
                //        boxGrids.Add(boxGrid);

                //    }
                //    await BoxGrid_res.InsertManyAsync(boxGrids);
                //    box.BoxGrids.Clear();
                //    box.BoxGrids.AddRange(boxGrids);
                //    box.BoxGridQuantity = (int)input.BoxGridQuantity;
                //    await Box_res.UpdateAsync(box);

                //}
                //return new ApiResponse("更新成功", true, null);

            }
            catch (Exception ex)
            {
                loginHelper.LoginAsync(input, "Update_Box");
                return new ApiResponse("内部服务器错误", false, null);
            }


        }
        public async Task<ApiResponse> Update_WarehouseLines(InPut_BaseService5 inPut)//更新仓位状态
        {
            try
            {
                foreach (var item in inPut.WarehouseLineCodes)
                {
                    WarehouseLine warehouseLine = await WarehouseLine_res.FirstOrDefaultAsync(x => x.WarehouseLineCode == item);
                    if (warehouseLine != null)
                    {
                        warehouseLine.IsEnable = inPut.Type;
                    }
                    await WarehouseLine_res.UpdateAsync(warehouseLine);
                }
                return new ApiResponse("修改成功", true, null);

            }
            catch (Exception ex)
            {
                loginHelper.LoginAsync(inPut, "Update_WarehouseLines");
                return new ApiResponse("ERROR-Update_WarehouseLines", false, null);
            }



        }
        public async Task<ApiResponse> UpdateTaskOrderState(InPut_BaseService11 InPut)//修改任务状态
        {
            try
            {
                TaskOrder taskOrder = await TaskOrder_res.FirstOrDefaultAsync(x => x.TaskOrderCode == InPut.TaskOrderCode);
                if (taskOrder == null)
                {
                    return new ApiResponse("未查询到单号", false, null);
                }
                taskOrder.State = InPut.Type;
                await TaskOrder_res.UpdateAsync(taskOrder);
                return new ApiResponse("修改成功", true, null);
            }
            catch (Exception ex)
            {


                loginHelper.LoginAsync(InPut, "UpdateTaskOrderState");
                return new ApiResponse("ERROR-UpdateTaskOrderState", false, null);
            }
        }
        public async Task<ApiResponse> GetList_InlethouesCode(string Type)
        {
            try
            {
                List<InlethouseLine> inlethouseLines = await Inlethouseline_res.GetListAsync(x => x.Type == Type);
                List<string> InlethouseCodes = inlethouseLines.Select(x => x.InlethouseLineCode).ToList();
                return new ApiResponse("获取成功", true, InlethouseCodes);
            }
            catch (Exception ex)
            {
                loginHelper.LoginInfoAsync($"GetList_InlethouesCode-{Type}");


                return new ApiResponse("ERROR-GetList_InlethouesCode", false, null);
            }
        }//获取出口   
        public async Task<ApiResponse> DeleteBox(InPut_BaseService8 InPut)//删箱子
        {
            try
            {
                //List<Box> BoxDel = new List<Box>();
                //if (string.IsNullOrEmpty(InPut.EndBoxCode))
                //{
                //    BoxDel.Add(await Box_res.FirstOrDefaultAsync(x => x.BoxCode == InPut.BoxCode));
                //}
                //else
                //{
                //    List<Box> boxes=  await Box_res.GetListAsync();
                //    BoxDel = boxes.Where(x => int.Parse(x.BoxCode.Substring(x.BoxCode.Length - 4)) >=
                //                            int.Parse(InPut.BoxCode.Substring(InPut.BoxCode.Length - 4)) &&
                //                            int.Parse(x.BoxCode.Substring(x.BoxCode.Length -4)) <=
                //                            int.Parse(InPut.EndBoxCode.Substring(InPut.EndBoxCode.Length - 4))).ToList();
                //}
                //bool res= BoxDel.Any(x => x.BoxGrids.Any(y => y.materialBase != null));
                //if (res)
                //{
                //    return new ApiResponse("有物料,无法删除", false, null);
                //}
                //await Box_res.DeleteManyAsync(BoxDel);
                return new ApiResponse("删除成功", true, null);
            }
            catch (Exception ex)
            {

                loginHelper.LoginAsync(InPut, "DeleteBox");
                return new ApiResponse("内部错误服务器", false, null);
            }

        }
        public async Task<ApiResponse> test(InPut_EssService InPut)
        {
            List<Box> boxes= await Box_res.GetListAsync();
            foreach (var item in boxes)
            {
                List<BoxGrid> boxGrids = new List<BoxGrid>();
                for (int y = 0; y <1; y++)//格
                {
   
                        BoxGrid boxGrid = new BoxGrid();
                        string BoxGridCode = $"{item.BoxCode}_{(y + 1)}";
                        boxGrid = boxGrid.AddBoxGrid(y + 1, BoxGridCode, item, 10);
                        boxGrids.Add(boxGrid);
                        List<BoxPosition> boxPositions = new List<BoxPosition>();
                        for (int x = 1; x <= 10; x++)
                        {
                            BoxPosition boxPosition = new BoxPosition();
                            string BoxPositionCode = $"{BoxGridCode}_{x}";
                            boxPosition = boxPosition.AddBoxPosition(BoxPositionCode, boxGrid, x);
                            boxPositions.Add(boxPosition);
                        }
                        await BoxPosition_res.InsertManyAsync(boxPositions);
                       await BoxGrid_res.InsertManyAsync(boxGrids);

                }
                item.BoxGrids.AddRange(boxGrids);
            }

            return new ApiResponse("未查询到在盒物料", false, null);
        }
        public async Task<ApiResponse> RemovesMaterial(List<string> MaterialCodes)//删料
        {
            try
            {
                List<MaterialBase> materialBases = await MaterialBase_res.GetListAsync(x => MaterialCodes.Any(y => y == x.MaterialCode));
                materialBases.ForEach(x => x.Id_BoxPosition = null);
                await MaterialBase_res.DeleteManyAsync(materialBases);
                return new ApiResponse("删除成功", true, null);
            }
            catch (Exception ex)
            {
                loginHelper.LoginAsync(MaterialCodes, "RemovesMaterial");

                return new ApiResponse("ERROR-RemovesMaterial", false, null);
            }

        }
        public async Task<ApiResponse> UpdateMaterialBaserQuantity(InPut_BaseService7 inPut)//更新物料数量
        {
            try
            {
                //var MaterialBases = await MaterialBase_res.WithDetailsAsync();
                //MaterialBase materialBaseJudge = await MaterialBases.FirstOrDefaultAsync(x => x.MaterialProperty.MaterialProertyname == inPut.MaterialProertyName && x.BoxGrid.TheBox.BoxCode== inPut.BoxCode);
                //if (materialBaseJudge == null) return new ApiResponse("未查询到物料", false, null);
                //#region  operate
                ////update materialbase 
                //materialBaseJudge.Quantity = materialBaseJudge.Quantity+ inPut.Quantity;
                //await MaterialBase_res.UpdateAsync(materialBaseJudge);
                return new ApiResponse("更新成功", true, null);

            }
            catch (Exception ex)
            {
                loginHelper.LoginAsync(inPut, "UpdateMaterialBaserQuantity");
                return new ApiResponse("ERROR-UpdateMaterialBaserQuantity", false, null);
            }
        }
        public async Task<ApiResponse> CreateMaterialProperty(InPut_BaseService14 InPut)//添加物料属性
        {
            try
            {
                MaterialProperty materialProperty = new MaterialProperty();
                materialProperty.MaterialProertyname = InPut.MaterialProertyname;
                materialProperty.Description = InPut.Description;
                materialProperty.Unit = InPut.Unit;
                materialProperty.Type = InPut.Type;
                await MaterialProperty_res.InsertAsync(materialProperty);
                return new ApiResponse("添加成功", true, null);
            }
            catch (Exception ex)
            {
                loginHelper.LoginAsync(InPut, "CreateMaterialProperty");
                return new ApiResponse("ERROR-CreateMaterialProperty", false, null);
            }
        }
        //使用中
        public async Task<ApiResponse> Create_Inlethouse(InPut_BaseService9 input)
        {
            try
            {

                bool result = await Inlethouseline_res.AnyAsync(x => x.Xaxis == input.Xaxis && x.Yaxis == input.Yaxis && x.Zaxis == input.Zaxis && x.Type == input.Type);
                if (result) return new ApiResponse("入出.库口已存在", false, null);
                Inlethouse inlethouse = new Inlethouse();
                inlethouse = inlethouse.AddInlethouse(input.InlethouseCode, input.Xaxis, input.Yaxis, input.Zaxis, input.InlethouseName, input.parameter);
                InlethouseLine inlethouseLine = new InlethouseLine();
                inlethouseLine = inlethouseLine.AddInlethouseline(input.Long, input.Wide, input.high, input.Xaxis, input.Yaxis, input.Zaxis, null, input.Type,input.LineType);
                inlethouseLine.InlethouseLineCode = input.InlethouseCode;
                inlethouseLine.TheInlethouse = inlethouse;
                inlethouse.inlethouselines.Add(inlethouseLine);
                await Inlethouse_res.InsertAsync(inlethouse);
                await Inlethouseline_res.InsertAsync(inlethouseLine);
                return new ApiResponse("配置成功", true, null);
            }
            catch (Exception ex)
            {


                loginHelper.LoginAsync(input, "Create_Inlethouse");
                return new ApiResponse("ERROR-Create_Inlethouse", false, null);
            }

        }//配置入库口
        public async Task<ApiResponse> Create_Warehouses(InPut_BaseService3 input)//配置库位
        {
            try
            {
                bool res = await Warehouse_res.AnyAsync(x => x.WarehouseName == input.WarehouseName);
                if (res)
                {
                    return new ApiResponse("库位名称重复", false, null);
                }
                BoxType binType = await BoxType_res.FirstOrDefaultAsync(x => x.BoxType_Name == input.BinType_Name);
                if (binType == null)
                {
                    return new ApiResponse("查询不到的Bintype", false, null);
                }
                Warehouse warehouse = new Warehouse();
                warehouse = warehouse.AddWarehouse(input.WarehouseCode, input.Xaxis, input.Yaxis, input.Zaxis, input.WarehouseName, input.parameter, input.Type);
                await Warehouse_res.InsertAsync(warehouse);
                int sum = input.Xaxis * input.Yaxis * input.Zaxis;
                List<WarehouseLine> lines = new List<WarehouseLine>();
                //排
                for (int j = 1; j <= input.Xaxis; j++)
                {
                    //高
                    for (int k = 1; k <= input.Yaxis; k++)
                    {
                        //列
                        for (int y = 1; y <= input.Zaxis; y++)
                        {
                            if (!input.Double)
                            {
                                WarehouseLine warehouseLine = new WarehouseLine();
                                warehouseLine = warehouseLine.AddWarehouseline(binType.Width, binType.Height, binType.DePth, j, k, y, warehouse, binType);
                                warehouseLine.WarehouseLineCode = warehouse.WarehouseCode + "-" + j.ToString("D3") + "-" + k.ToString("D3") + "-" + y.ToString("D2");
                                lines.Add(warehouseLine);
                            }
                            else
                            {
                                WarehouseLine warehouseLine = new WarehouseLine();
                                warehouseLine = warehouseLine.AddWarehouseline(binType.Width, binType.Height, binType.DePth, j, k, y, warehouse, binType);
                                warehouseLine.WarehouseLineCode = warehouse.WarehouseCode + "-" + j.ToString("D3") + "-" + k.ToString("D3") + "-" + y.ToString("D2") + "_1";
                                lines.Add(warehouseLine);
                                WarehouseLine warehouseLine2 = new WarehouseLine();
                                warehouseLine2 = warehouseLine2.AddWarehouseline(binType.Width, binType.Height, binType.DePth, j, k, y, warehouse, binType);
                                warehouseLine2.WarehouseLineCode = warehouse.WarehouseCode + "-" + j.ToString("D3") + "-" + k.ToString("D3") + "-" + y.ToString("D2") + "_2";
                                lines.Add(warehouseLine2);
                            }
                        }
                    }
                }
                warehouse.warehouselines.AddRange(lines);
                await Warehouse_res.InsertAsync(warehouse);
                await WarehouseLine_res.InsertManyAsync(lines);
                return new ApiResponse("配置成功", true, null);
            }
            catch (Exception ex)
            {
                loginHelper.LoginAsync(input, "Create_Warehouses");
                return new ApiResponse("ERROR-Create_Warehouses", false, null);
            }

        }
        public async Task<ApiResponse> Create_Inlethouses(InPut_BaseService9 input)//配置缓存货位
        {
            try
            {
                bool res = await Inlethouse_res.AnyAsync(x => x.InlethouseName == input.InlethouseName);
                if (res)
                {
                    return new ApiResponse("库位名称重复", false, null);
                }
                Inlethouse inlethouse = new Inlethouse();
                inlethouse = inlethouse.AddInlethouse(input.InlethouseCode, input.Xaxis, input.Yaxis, input.Zaxis, input.InlethouseName, input.parameter);
                await Inlethouse_res.InsertAsync(inlethouse);
                int sum = input.Xaxis * input.Yaxis * input.Zaxis;
                List<InlethouseLine> lines = new List<InlethouseLine>();
                //排
                for (int j = 1; j <= input.Xaxis; j++)
                {
                    //高
                    for (int k = 1; k <= input.Yaxis; k++)
                    {
                        //列
                        for (int y = 1; y <= input.Zaxis; y++)
                        {
                            InlethouseLine inlethouseLine = new InlethouseLine();
                            inlethouseLine = inlethouseLine.AddInlethouseline(input.Long, input.Wide, input.high, j, k, y, inlethouse, input.Type,null);
                            inlethouseLine.InlethouseLineCode = inlethouse.InlethouseCode + "-" + j.ToString("D2") + "-" + k.ToString("D2") + "-" + y.ToString("D2");
                            lines.Add(inlethouseLine);
                        }
                    }
                }
                inlethouse.inlethouselines.AddRange(lines);
                await Inlethouse_res.InsertAsync(inlethouse);
                await Inlethouseline_res.InsertManyAsync(lines);
                return new ApiResponse("配置成功", true, null);
            }
            catch (Exception ex)
            {


                loginHelper.LoginAsync(input, "Create_Inlethouses");
                return new ApiResponse("ERROR-Create_Inlethouses", false, null);
            }
        }
        public async Task<ApiResponse> Create_Boxs(InPut_BaseService input)//配置箱盒
        {
            try
            {

                bool res = await Box_res.AnyAsync(x => x.BoxCode.Substring(x.BoxCode.Length - 4) == input.StartNumber.ToString("D4") ||
                                                  x.BoxCode.Substring(x.BoxCode.Length - 4) == input.EndNumber.ToString("D4"));
                if (res)
                {
                    return new ApiResponse("箱盒已存在", false, null);
                }
                BoxType binType = await BoxType_res.FirstOrDefaultAsync(x => x.BoxType_Name == input.BinType_Name);
                if (binType == null)
                {
                    return new ApiResponse("查询不到的Bintype", false, null);
                }
                //配置箱盒
                int boxquantity = input.EndNumber - input.StartNumber + 1;
                List<Box> boxes = new List<Box>();
                for (int i = 0; i < boxquantity; i++)//箱
                {
                    Box box = new Box();
                    string BoxCode = input.Name + "00000" + (input.StartNumber + i).ToString("D4");
                    box = box.AddBox(BoxCode, input.BoxGridQuantity, input.VirtualSpace, binType);
                    List<BoxGrid> boxGrids = new List<BoxGrid>();
                    for (int y = 0; y < input.BoxGridQuantity; y++)//格
                    {
                        //有虚拟货位
                        if (input.VirtualSpace)
                        {
                            BoxGrid boxGrid = new BoxGrid();
                            string BoxGridCode = $"{BoxCode}_{(y + 1)}";
                            boxGrid = boxGrid.AddBoxGrid(y + 1, BoxGridCode, box, input.PostionQuantity);
                            boxGrids.Add(boxGrid);
                            List<BoxPosition> boxPositions = new List<BoxPosition>();
                            for (int x = 1; x <= input.PostionQuantity; x++)
                            {
                                BoxPosition boxPosition = new BoxPosition();
                                string BoxPositionCode = $"{BoxGridCode}_{x}";
                                boxPosition = boxPosition.AddBoxPosition(BoxPositionCode, boxGrid, x);
                                boxPositions.Add(boxPosition);
                            }
                            await BoxPosition_res.InsertManyAsync(boxPositions);
                        }
                        //无虚拟货位
                        else
                        {
                            BoxGrid boxGrid = new BoxGrid();
                            string BoxGridCode = $"{BoxCode}_{(y + 1)}";
                            boxGrid = boxGrid.AddBoxGrid(y + 1, BoxGridCode, box, 0);
                            boxGrids.Add(boxGrid);
                        }

                    }
                    await BoxGrid_res.InsertManyAsync(boxGrids);
                    box.BoxGrids.AddRange(boxGrids);
                    boxes.Add(box);
                }
                await Box_res.InsertManyAsync(boxes);
                return new ApiResponse("生成成功", true, null);
            }
            catch (Exception ex)
            {


                loginHelper.LoginAsync(input, "Create_Boxs");
                return new ApiResponse("ERROR-Create_Boxs", false, null);
            }
        }
        public async Task<ApiResponse> CreateTaskOrder(InPut_BaseService6 InPut)//添加agv入库任务
        {
            try
            {
                Box box = await context.boxs.Include(x => x.WarehouseLine).Include(x => x.BoxType).FirstOrDefaultAsync(x => x.BoxCode == InPut.BoxCode);
                BoxType boxTypeMix=  await BoxType_res.FirstOrDefaultAsync(x => x.BoxType_Name == "混合区");
                if (box == null)
                {
                    return new ApiResponse("未查询到箱盒", false, null);
                }
                if (box.WarehouseLine != null)
                {
                    return new ApiResponse("箱盒已在货架上", false, null);
                }
                List<WarehouseLine> warehouseLines = await WarehouseLine_res.GetListAsync(x => x.Box == null && x.IsEnable == true && (x.BoxType == box.BoxType||x.BoxType== boxTypeMix) && x.IsOccupy == false);
                if (warehouseLines.Count == 0)
                {
                    return new ApiResponse("库位已用完", false, null);
                }
                WarehouseLine warehouseLine = warehouseLines.OrderBy(x => Random.Shared.Next()).First();
                var inlethouseLines = await Inlethouseline_res.WithDetailsAsync();
                InlethouseLine inlethouseLine = await inlethouseLines.FirstOrDefaultAsync(x => x.Box == null && x.IsEnable == true && x.InlethouseLineCode.Contains(InPut.InletCode)&&x.LineType=="出口");
                if (inlethouseLine == null)
                {
                    return new ApiResponse("缓存货架已用完/查询不到", false, null);
                }
                bool res = await TaskOrder_res.AnyAsync(x => x.Id_Box == box.Id_Box);
                if (res) return new ApiResponse("已存在相同箱盒任务/或者任务还没结束,检查ESS任务系统去！！！", false, null);
                TaskOrder taskOrder = new TaskOrder();
                taskOrder.Box = box;
                taskOrder.Type = "入库";
                taskOrder.WarehouseCode = warehouseLine.WarehouseLineCode;
                taskOrder.InlethouseCode = inlethouseLine.InlethouseLineCode;
                taskOrder.CreatTime = DateTime.Now;
                taskOrder.State = "未下发";
                taskOrder.TaskOrderCode = ExtendRandom.CreateRandom();
                box.TaskOrder = taskOrder;
                await Box_res.UpdateAsync(box);
                await TaskOrder_res.InsertAsync(taskOrder);
                warehouseLine.IsOccupy = true;
                await WarehouseLine_res.UpdateAsync(warehouseLine);
                inlethouseLine.IsOccupy = true;
                await Inlethouseline_res.UpdateAsync(inlethouseLine);
                return new ApiResponse("任务生成成功", true, inlethouseLine.InlethouseLineCode);
            }
            catch (Exception ex)
            {


                loginHelper.LoginAsync(InPut, "CreateTaskOrder");
                return new ApiResponse("ERROR-CreateTaskOrder", false, null);
            }

        }
        public async Task<ApiResponse> DeleteTaskOrder(List<string> TaskOrderCodes)
        {
            try
            {
                List<TaskOrder> taskOrders = await TaskOrder_res.GetListAsync(x => TaskOrderCodes.Any(y => y == x.TaskOrderCode));
                List<WarehouseLine> warehouseLines = await WarehouseLine_res.GetListAsync();
                warehouseLines = warehouseLines.Where(x => taskOrders.Any(y => y.WarehouseCode == x.WarehouseLineCode)).ToList();
                List<InlethouseLine> inlethouseLines = await Inlethouseline_res.GetListAsync();
                inlethouseLines = inlethouseLines.Where(x => taskOrders.Any(y => y.InlethouseCode == x.InlethouseLineCode)).ToList();
                List<Box> boxs = await context.boxs.Include(x=>x.BoxGrids).ThenInclude(x=>x.BoxPositions).ThenInclude(x=>x.MaterialBase).ToListAsync();                                
                boxs = boxs.Where(x => taskOrders.Any(y => y.Id_Box == x.Id_Box)).ToList();
                bool res = taskOrders.Any(x => x.State != "未下发");
                if (res) { return new ApiResponse("只能删除未下发的任务", false, null); }
         
                if (taskOrders.All(x => x.Type == "入库"))
                {
                    warehouseLines.ForEach(x => x.IsOccupy = false);
                    await WarehouseLine_res.UpdateManyAsync(warehouseLines);
                }
                inlethouseLines.ForEach(x =>
                {
                    x.IsOccupy = false;
                    x.Box = null;
                });
                boxs.ForEach(x =>
                {
                    x.InlethouseLine = null;
                    foreach (var boxGrid in x.BoxGrids)
                    {
                        foreach (var boxPosition in boxGrid.BoxPositions)
                        {
                            if (boxPosition.MaterialBase != null)
                            {
                                boxPosition.MaterialBase.Islock = false;
                            }
                       
                        }
                    }
                });
                await Inlethouseline_res.UpdateManyAsync(inlethouseLines);
                await Box_res.UpdateManyAsync(boxs);
                await TaskOrder_res.DeleteManyAsync(taskOrders);
                loginHelper.LoginInfoAsync($"DeleteTaskOrder{TaskOrderCodes}");
                return new ApiResponse("已删除任务", true, null);
            }
            catch (Exception ex)
            {

                loginHelper.LoginErrorAsync($"DeleteTaskOrder{TaskOrderCodes}" + ex);
                return new ApiResponse("ERROR-DeleteTaskOrder", false, null);
            }

        }//删除任务 
        public async Task<ApiResponse> CreateTaskOrderOut(InPut_BaseService13 InPut)//agv出库任务
        {
            try
            {
                List<TaskOrder> taskOrders = await TaskOrder_res.WithDetails().ToListAsync();
                List<TaskOrder> taskOrdersDel = taskOrders.Where(x => InPut.BoxCodes.Any(y => y == x.Box.BoxCode)).ToList();
                List<Box> boxes = await Box_res.WithDetails().ToListAsync();
                boxes = boxes.Where(x => InPut.BoxCodes.Any(y => y == x.BoxCode)).ToList();
                boxes = boxes.Where(x => !taskOrdersDel.Any(y => y.Id_Box == x.Id_Box)).ToList();
                bool res = boxes.Any(x => x.WarehouseLine == null);
                if (res)
                {
                    return new ApiResponse("有料盒不在货架上", false, null);
                }
                if (InPut.BoxCodes.Count > 12)
                {
                    return new ApiResponse("一次最多下方12个任务", false, null);
                }

                InlethouseLine inlethouseLine = await Inlethouseline_res.FirstOrDefaultAsync(x => x.InlethouseLineCode.Contains(InPut.InlethouseCode)&&x.LineType=="入口");
                if (inlethouseLine == null)
                {
                    return new ApiResponse("查询不到的出库口", false, null);
                }
                List<TaskOrder> taskOrdersInsert = new List<TaskOrder>();
                inlethouseLine.IsOccupy = true;
                int i = 0;
                foreach (var item in boxes)
                {
                    TaskOrder taskOrder = new TaskOrder();
                    taskOrder = taskOrder.AddTaskOrder("出库", item, item.WarehouseLine.WarehouseLineCode, inlethouseLine.InlethouseLineCode, null, null, null,"未下发");
                    taskOrdersInsert.Add(taskOrder);
                    i++;
                }

                await TaskOrder_res.InsertManyAsync(taskOrdersInsert);
                await Inlethouseline_res.UpdateAsync(inlethouseLine);
                List<TaskOrderDto> Dto = ObjectMapper.Map<List<TaskOrder>, List<TaskOrderDto>>(taskOrdersInsert);
                return new ApiResponse("任务生成成功", true, Dto);
            }
            catch (Exception ex)
            {


                loginHelper.LoginAsync(InPut, "CreateTaskOrderOut");
                return new ApiResponse("ERROR-CreateTaskOrderOut", false, null);
            }
        }
        public async Task<ApiResponse> Create_Bintype(InPut_BaseService16 InPut)//配置bin
        {
            try
            {
                bool binTypeCheck = await BoxType_res.AnyAsync(x => x.BoxType_Name == InPut.BinType_Name);
                if (binTypeCheck)
                {
                    return new ApiResponse("BinName重复", false, null);
                }
                BoxType binType = new BoxType();
                binType.BoxType_Name = InPut.BinType_Name;
                binType.DePth = InPut.DePth;
                binType.Width = InPut.Width;
                binType.Height = InPut.Height;
                await BoxType_res.InsertAsync(binType);
                return new ApiResponse("添加Bintype成功", true, null);
            }
            catch (Exception ex)
            {


                loginHelper.LoginAsync(InPut, "Create_Bintype");
                return new ApiResponse("ERROR-Create_Bintype", false, null);
            }

        }
        public async Task<ApiResponse> Getlist_Bintypes()//获取bins
        {
            List<BoxType> binTypes = await BoxType_res.GetListAsync();
            return new ApiResponse("添加Bintype成功", true, binTypes);
        }
        public async Task<ApiResponse> CreateNeetOutMaterial(InPut_BaseService10 InPut)//手动出库-添加需出料-添加agv任务-输送线
        {
            try
            {
                //List<MaterialBase> materialBases = await MaterialBase_res.GetListAsync(x =>InPut. MaterialCodes.Any(y => y == x.MaterialCode));
                List<MaterialBase> materialBases = MaterialBase_res.WithDetails().ToList();
                List<NeetOutMaterial> NeetOutMaterials = await NeetOutMaterial_res.GetListAsync(x => InPut.MaterialuniqueCodes.Any(y => y == x.Material.MaterialuniqueCode));
                List<string> MaterialuniqueCodesDel = NeetOutMaterials.Select(x => x.Material.MaterialuniqueCode).ToList();
                InPut.MaterialuniqueCodes = InPut.MaterialuniqueCodes.Except(MaterialuniqueCodesDel).ToList();
                materialBases = materialBases.Where(x => InPut.MaterialuniqueCodes.Any(y => y == x.MaterialuniqueCode)).ToList();
                //var taskOrders = await TaskOrder_res.GetListAsync(x => materialBases.Any(y => y.Info== x.Box.BoxCode));
                List<TaskOrder> taskOrders = await TaskOrder_res.WithDetails().ToListAsync();
                taskOrders = taskOrders.Where(x => materialBases.Any(y => y.BoxPosition.TheBoxGrid.TheBox.BoxCode == x.Box.BoxCode && x.Type == "出库")).ToList();
                List<TaskOrder> taskOrderLussed = taskOrders.Where(x => x.State == "已下发").ToList();
                if (taskOrderLussed.Count > 0)
                {
                    return new ApiResponse(taskOrders[0].Box.BoxCode + "已发送AGV任务,无法再次添加出库", false, null);
                }
                bool RES= materialBases.Any(X => X.Islock == true);
                if (RES)
                {
                    return new ApiResponse("已经锁定的物料无法再次被选中", false, null);
                }
                List<MaterialBase> materialBasesTask = materialBases.DistinctBy(x => x.BoxPosition.TheBoxGrid.TheBox.BoxCode).ToList();
                InlethouseLine inlethouseLine = await Inlethouseline_res.FirstOrDefaultAsync(x => x.InlethouseLineCode == InPut.InlethouseCode);
                if (inlethouseLine == null)
                {
                    return new ApiResponse(InPut.InlethouseCode + "未查询到的出库口", false, null);
                }
                #region operate
                //creater neetOutMaterial
                List<NeetOutMaterial> neetOutMaterials = new List<NeetOutMaterial>();

                foreach (var materialBase in materialBases)
                {
                    NeetOutMaterial neetOutMaterial = new NeetOutMaterial();
                    neetOutMaterial = neetOutMaterial.AddNeetOutMaterial(materialBase, "手动出库", materialBase.Quantity, null, null, null);

                    neetOutMaterials.Add(neetOutMaterial);
                    materialBase.Islock = true;
                    materialBase.NeetOutMaterials.Add(neetOutMaterial);
                }
                ////creater taskorder


                List<TaskOrder> taskOrderNotfinsih = taskOrders.ToList();
                materialBasesTask = materialBasesTask.Where(x => !taskOrderNotfinsih.Any(y => y.Box.BoxCode == x.BoxPosition.TheBoxGrid.TheBox.BoxCode)).ToList();//去掉已在任务中有的箱盒
                int i = 0;
                List<TaskOrder> taskorderDto = new List<TaskOrder>();
                foreach (var item in materialBasesTask)
                {
                    TaskOrder taskOrder = new TaskOrder();
                    taskOrder = taskOrder.AddTaskOrder("出库", item.BoxPosition.TheBoxGrid.TheBox, item.BoxPosition.TheBoxGrid.TheBox.WarehouseLine.WarehouseLineCode, inlethouseLine.InlethouseLineCode, "手动出库", null, null,"未下发");
                    item.BoxPosition.TheBoxGrid.TheBox.TaskOrder = taskOrder;
                    inlethouseLine.IsOccupy = true;
                    foreach (var neetOutMaterial in neetOutMaterials)
                    {
                        if (neetOutMaterial.Material.BoxPosition.TheBoxGrid.TheBox.Id_Box == taskOrder.Box.Id_Box)
                        {
                            neetOutMaterial.TheTaskOrder = taskOrder;
                        }
                    }
                    await Box_res.UpdateAsync(item.BoxPosition.TheBoxGrid.TheBox);
                    taskorderDto.Add(taskOrder);
                    i++;
                }
                //已经加入任务的箱子的需要出的物料添加任务外键
                foreach (var neetOutMaterial in neetOutMaterials)
                {
                    foreach (var taskOrder in taskOrders)
                    {
                        if (neetOutMaterial.Material.BoxPosition.TheBoxGrid.TheBox.Id_Box == taskOrder.Box.Id_Box && neetOutMaterial.TheTaskOrder == null)
                        {
                            neetOutMaterial.TheTaskOrder = taskOrder;
                        }
                    }

                }




                List<TaskOrderDto> Dto = ObjectMapper.Map<List<TaskOrder>, List<TaskOrderDto>>(taskorderDto);
                await NeetOutMaterial_res.InsertManyAsync(neetOutMaterials);
                await TaskOrder_res.InsertManyAsync(taskorderDto);
                await MaterialBase_res.UpdateManyAsync(materialBases);
                await Inlethouseline_res.UpdateAsync(inlethouseLine);
                return new ApiResponse("已添加至需出料", true, Dto);
                #endregion
            }

            catch (Exception ex)
            {
                loginHelper.LoginAsync(InPut, "CreateNeetOutMaterial");
                return new ApiResponse("ERROR-CreateNeetOutMaterial", false, null);
            }
        }
        public async Task<ApiResponse> UpdateBoxBoxType(InPut_BaseService22 InPut)
        {
            BoxType boxType=  await BoxType_res.FirstOrDefaultAsync(x => x.BoxType_Id == InPut.BoxType_Id);
            if (boxType == null)
            {
                return new ApiResponse("未查询到的boxType", false, null);
            }
          List<Box> boxes=    await Box_res.GetListAsync(x => InPut.Id_Boxs.Any(y=>y==x.Id_Box));
            foreach (var box in boxes)
            {
                box.BoxType = boxType;

            }
            await Box_res.UpdateManyAsync(boxes);
            return new ApiResponse("已更新成功", true, null);
        }//更新箱盒类型
        public async Task<ApiResponse> UpdateWarehouselineBoxType(InPut_BaseService23 InPut)
        {
            BoxType boxType = await BoxType_res.FirstOrDefaultAsync(x => x.BoxType_Id == InPut.BoxType_Id);
            if (boxType == null)
            {
                return new ApiResponse("未查询到的boxType", false, null);
            }
            List<WarehouseLine > warehouseLines=     await WarehouseLine_res.GetListAsync(WarehouseLine_res => InPut.Id_WarehouseLines.Any(y => y == WarehouseLine_res.Id_WarehouseLine&& WarehouseLine_res.Box==null));
           
            
            foreach (var  warehouse in warehouseLines)
            {
                warehouse .BoxType = boxType;
            }
            await WarehouseLine_res.UpdateManyAsync(warehouseLines);
            return new ApiResponse("已更新成功", true, null);
        }//更新仓库类型
        //手动出库-添加需出料-添加agv任务-缓存货架
        //try
        //{
        //    //List<MaterialBase> materialBases = await MaterialBase_res.GetListAsync(x =>InPut. MaterialCodes.Any(y => y == x.MaterialCode));
        //    List<MaterialBase> materialBases = MaterialBase_res.WithDetails().ToList();
        //    List<NeetOutMaterial> NeetOutMaterials = await NeetOutMaterial_res.GetListAsync(x => InPut.MaterialuniqueCodes.Any(y => y == x.Material.MaterialuniqueCode));
        //    List<string> MaterialuniqueCodesDel = NeetOutMaterials.Select(x => x.Material.MaterialuniqueCode).ToList();
        //    InPut.MaterialuniqueCodes = InPut.MaterialuniqueCodes.Except(MaterialuniqueCodesDel).ToList();
        //    materialBases = materialBases.Where(x => InPut.MaterialuniqueCodes.Any(y => y == x.MaterialuniqueCode)).ToList();
        //    //var taskOrders = await TaskOrder_res.GetListAsync(x => materialBases.Any(y => y.Info== x.Box.BoxCode));
        //    List<TaskOrder> taskOrders = await TaskOrder_res.WithDetails().ToListAsync();
        //    taskOrders = taskOrders.Where(x => materialBases.Any(y => y.BoxPosition.TheBoxGrid.TheBox.BoxCode == x.Box.BoxCode && x.Type == "出库")).ToList();
        //    List<TaskOrder> taskOrderLussed = taskOrders.Where(x => x.State == "已下发").ToList();
        //    if (taskOrderLussed.Count > 0)
        //    {
        //        return new ApiResponse(taskOrders[0].Box.BoxCode + "已发送AGV任务,无法再次添加出库", false, null);
        //    }
        //    List<MaterialBase> materialBasesTask = materialBases.DistinctBy(x => x.BoxPosition.TheBoxGrid.TheBox.BoxCode).ToList();
        //    List<InlethouseLine> inlethouseLine\ = await Inlethouseline_res.GetListAsync(x => x.IsOccupy == false && x.Box == null && x.InlethouseLineCode.Contains(InPut.InlethouseCode));
        //    if (materialBasesTask.Count > inlethouseLine\.Count)
        //    {
        //        return new ApiResponse("当前可用缓存不够,请减少任务", false, null);
        //    }

        //    #region operate
        //    //creater neetOutMaterial
        //    List<NeetOutMaterial> neetOutMaterials = new List<NeetOutMaterial>();

        //    foreach (var materialBase in materialBases)
        //    {
        //        NeetOutMaterial neetOutMaterial = new NeetOutMaterial();
        //        neetOutMaterial = neetOutMaterial.AddNeetOutMaterial(materialBase, "手动出库", materialBase.Quantity, null, null, null);

        //        neetOutMaterials.Add(neetOutMaterial);

        //        materialBase.NeetOutMaterials.Add(neetOutMaterial);
        //    }
        //    await NeetOutMaterial_res.InsertManyAsync(neetOutMaterials);
        //    ////creater taskorder


        //    List<TaskOrder> taskOrderNotfinsih = taskOrders.ToList();
        //    materialBasesTask = materialBasesTask.Where(x => !taskOrderNotfinsih.Any(y => y.Box.BoxCode == x.BoxPosition.TheBoxGrid.TheBox.BoxCode)).ToList();//去掉已在任务中有的箱盒
        //    int i = 0;
        //    List<TaskOrder> taskorders = new List<TaskOrder>();
        //    foreach (var item in materialBasesTask)
        //    {
        //        TaskOrder taskOrder = new TaskOrder();
        //        taskOrder = taskOrder.AddTaskOrder("出库", item.BoxPosition.TheBoxGrid.TheBox, item.BoxPosition.TheBoxGrid.TheBox.WarehouseLine.WarehouseLineCode, inlethouseLine\[i].InlethouseLineCode, "手动出库", null, null);
        //        item.BoxPosition.TheBoxGrid.TheBox.TaskOrder = taskOrder;
        //        inlethouseLine\[i].IsOccupy = true;
        //        foreach (var neetOutMaterial in neetOutMaterials)
        //        {
        //            if (neetOutMaterial.Material.BoxPosition.TheBoxGrid.TheBox.Id_Box == taskOrder.Box.Id_Box)
        //            {
        //                neetOutMaterial.TheTaskOrder = taskOrder;
        //            }
        //        }

        //        await Box_res.UpdateAsync(item.BoxPosition.TheBoxGrid.TheBox);
        //        taskorders.Add(taskOrder);
        //        i++;
        //    }
        //    List<TaskOrderDto> Dto = ObjectMapper.Map<List<TaskOrder>, List<TaskOrderDto>>(taskorders);
        //    await NeetOutMaterial_res.InsertManyAsync(neetOutMaterials);
        //    await TaskOrder_res.InsertManyAsync(taskOrders);
        //    await MaterialBase_res.UpdateManyAsync(materialBases);
        //    await Inlethouseline_res.UpdateManyAsync(inlethouseLine\);
        //    return new ApiResponse("已添加至需出料", true, Dto);
        //    #endregion
        //}

        //catch (Exception ex)
        //{
        //    loginHelper.LoginAsync(InPut, "CreateNeetOutMaterial");
        //    return new ApiResponse("CreateNeetOutMaterial-ERROR", false, null);
        //}
        public async Task<ApiResponse> DeleteMaterial(InPut_BaseService4 input)//取料确认
        {
            try
            {
                View_NeetOutMaterial view_NeetOutMaterial = await context.View_NeetOutMaterials.FirstOrDefaultAsync(x => x.BoxPositionCode.Contains(input.BoxPositionCode)
                && x.MaterialName==input.MaterialName&&x.Poundage==input.Poundage);
                if (view_NeetOutMaterial == null)
                {
                    return new ApiResponse("未查询到需出料", false, null);
                }
                var materialBases = await MaterialBase_res.WithDetailsAsync();
                MaterialBase materialBase = await materialBases.FirstOrDefaultAsync(x => x.MaterialuniqueCode == view_NeetOutMaterial.MaterialuniqueCode);
                if (materialBase == null)
                {
                    return new ApiResponse($"未查询到实物{view_NeetOutMaterial.Consumer_MaterialId}", false, null);
                }
                if (materialBase.BoxPosition.TheBoxGrid.TheBox.WarehouseLine != null)
                {
                    return new ApiResponse($"检查到{materialBase.BoxPosition.TheBoxGrid.TheBox.BoxCode}未下架", false, null);
                }
                //update materialbase
                await MaterialBase_res.DeleteAsync(materialBase);
                //delete neetoutmaterial
                await NeetOutMaterial_res.DeleteAsync(x => x.Id_NeetOutMaterial == view_NeetOutMaterial.Id_NeetOutMaterial);
                //CREATE  LOG
                lognote lognote = new lognote();
                lognote.DateTime = DateTime.Now;
                lognote.User = User.UserName;
                lognote.Type = "出库";
                lognote.Note = $"物料名称:{view_NeetOutMaterial.MaterialName}-重量:{view_NeetOutMaterial.Poundage}-箱盒:{view_NeetOutMaterial.BoxPositionCode}";
                await LogNote_res.InsertAsync(lognote);
                return new ApiResponse("取料成功,请取走物料", true, view_NeetOutMaterial.BoxPositionCode);
            }
            catch (Exception ex)
            {
                loginHelper.LoginAsync(input, "DeleteMaterial");
                return new ApiResponse("ERROR-DeleteMaterial", false, ex);
            }
        }
        public async Task<ApiResponse> UpdateState_ByWarehouselineId(InPut_BaseService17 InPut)//更新货位状态
        {
            try
            {
                WarehouseLine warehouseLine = await WarehouseLine_res.FirstOrDefaultAsync(x => x.Id_WarehouseLine == InPut.Id_WarehouseLine);
                if (warehouseLine == null)
                {
                    return new ApiResponse("未查询到库位", false, null);
                }
                warehouseLine.IsEnable = InPut.IsEnable;
                await WarehouseLine_res.UpdateAsync(warehouseLine);
                return new ApiResponse("更新成功", true, null);
            }catch(Exception ex)
            {
                loginHelper.LoginAsync(InPut, "UpdateState_ByWarehouselineId");
                return new ApiResponse("ERROR-UpdateState_ByWarehouselineId", false, ex);
            }
     

        }
        public async Task<ApiResponse> UpdateState_ByInlethouselineId(InPut_BaseService18 InPut)//更新入口状态
        {
            try
            {
                InlethouseLine inlethouseLine = await Inlethouseline_res.FirstOrDefaultAsync(x => x.Id_InlethouseLine == InPut.Id_InlethouseLine);
                if (inlethouseLine == null)
                {
                    return new ApiResponse("未查询到库位", false, null);
                }
                inlethouseLine.IsEnable = InPut.IsEnable;
                await Inlethouseline_res.UpdateAsync(inlethouseLine);
                return new ApiResponse("更新成功", true, null);
            }catch(Exception ex)
            {
                loginHelper.LoginAsync(InPut, "UpdateState_ByInlethouselineId");
                return new ApiResponse("ERROR-UpdateState_ByInlethouselineId", false, ex);
            }
  
        }
        public async Task<ApiResponse> UpdateNeetQuantity(InPut_BaseService19 InPut)//修改出库数量
        {
            try
            {
                NeetOutMaterial neetOutMaterial = await context.neetOutMaterials.Include(x => x.Material).FirstOrDefaultAsync(x => x.Id_NeetOutMaterial == InPut.Id_NeetOutMaterial);
                if (neetOutMaterial == null)
                {
                    return new ApiResponse("未查询到出库需求", false, null);
                }
                //updateneetoutmaterial
                neetOutMaterial.NeetQuantity = InPut.NeetQuantity;
                await NeetOutMaterial_res.UpdateAsync(neetOutMaterial);
                //CREATE  LOG
                lognote lognote = new lognote();
                lognote.DateTime = DateTime.Now;
                lognote.User = User.UserName;
                lognote.Type = "修改";
                lognote.Note = $"物料Id:{neetOutMaterial.Material.Consumer_MaterialId}-修改数量:{InPut.NeetQuantity}-工单:{neetOutMaterial.OrderNo}";
                await LogNote_res.InsertAsync(lognote);
                return new ApiResponse($"修改成功{neetOutMaterial.Material.Consumer_MaterialId}", true, null);
            }catch(Exception ex)
            {
                loginHelper.LoginAsync(InPut, "UpdateNeetQuantity");
                return new ApiResponse("ERROR-UpdateNeetQuantity", false, ex);
            }
   
        }
        public async Task<ApiResponse> AllocationOrder(InPut_BaseService20 InPut)//分配出库工单-添加需出料
        {
            try
            {
                List<PutOutOrder> putOutOrders = await PutOutOrder_res.GetListAsync(x => x.Symbol == InPut.Symbol && x.State == "待分配");
                if (putOutOrders.Count == 0)
                {
                    return new ApiResponse("不存在/或已分配的工单", false, null);
                }
                List<MaterialBase> materialBases = await MaterialBase_res.GetListAsync(x => x.Islock == false && x.BoxPosition.TheBoxGrid.TheBox.WarehouseLine != null);
                materialBases = materialBases.Where(x => putOutOrders.Any(y => y.Batch == x.Batch && y.MaterialCode == x.MaterialCode)).ToList();

                List<NeetOutMaterial> neetOutMaterials = new List<NeetOutMaterial>();
                foreach (var putOutOrder in putOutOrders)
                {
                    int OutBoundQuantity = putOutOrder.OutBoundQuantity;
                    materialBases = materialBases.OrderBy(x => x.CreatedDate).ToList();
                    foreach (var materialBase in materialBases)
                    {
                        if (materialBase.Islock || materialBase.MaterialCode != putOutOrder.MaterialCode && materialBase.Batch != putOutOrder.Batch)
                        {
                            continue;
                        }
                        if (OutBoundQuantity <= 0)
                        {
                            break;
                        }
                        NeetOutMaterial neetOutMaterial = new NeetOutMaterial();
                        int quantity;
                        if (materialBase.Quantity <= OutBoundQuantity)
                        {
                            quantity = (int)materialBase.Quantity;
                        }
                        else
                        {
                            quantity = OutBoundQuantity;
                        }
                        neetOutMaterial = neetOutMaterial.AddNeetOutMaterial(materialBase, putOutOrder.Symbol, quantity, null, null, null);
                        neetOutMaterials.Add(neetOutMaterial);
                        materialBase.Islock = true;
                        materialBase.NeetOutMaterials.Add(neetOutMaterial);
                        OutBoundQuantity = OutBoundQuantity - quantity;
                    }
                    if (OutBoundQuantity <= 0)
                    {
                        putOutOrder.State = "已分配";
                    }
                    else
                    {
                        putOutOrder.State = "缺料";
                    }

                }
                await PutOutOrder_res.UpdateManyAsync(putOutOrders);
                await NeetOutMaterial_res.InsertManyAsync(neetOutMaterials);
                return new ApiResponse("分配成功", true, null);
            }catch(Exception ex)
            {
                loginHelper.LoginAsync(InPut, "AllocationOrder");
                return new ApiResponse("ERROR-AllocationOrder", false, ex);
            }
  
        }
        public async Task<ApiResponse> Deallocate(string Symbol)//解除分配
        {


            try
            {
                TaskOrder taskOrder = await TaskOrder_res.FirstOrDefaultAsync(x => x.OrderNo == Symbol);
                if (taskOrder != null)
                {
                    return new ApiResponse("已经下架的物料无法解除分配", false, null);
                }
                //update putoutorder
                List<PutOutOrder> putOutOrders = await PutOutOrder_res.GetListAsync(x => x.Symbol == Symbol);
                putOutOrders.ForEach(x =>
                {
                    x.State = "待分配";
                });
                await PutOutOrder_res.UpdateManyAsync(putOutOrders);
                //update material
                List<NeetOutMaterial> neetOutMaterials = await NeetOutMaterial_res.GetListAsync(x => x.OrderNo == Symbol);
                List<MaterialBase> materialBases = await MaterialBase_res.GetListAsync(x => x.NeetOutMaterials.Any(y => y.OrderNo == Symbol));
                materialBases.ForEach(x =>
                {
                    x.Islock = false;
                });
                await MaterialBase_res.UpdateManyAsync(materialBases);
                //delete neetoutmaterials
                await NeetOutMaterial_res.DeleteManyAsync(neetOutMaterials);
                return new ApiResponse("解除成功", true, null);
            }catch(Exception ex)
            {
                loginHelper.LoginErrorAsync("Deallocate:"+ex.ToString());
                return new ApiResponse("ERROR-Deallocate", false, ex);
            }



        }
        public async Task<ApiResponse> AllocationOrderAgvTask(InPut_BaseService21 InPut)
        {
            try
            {
                List<NeetOutMaterial> neetOutMaterials = await context.neetOutMaterials.Include(x => x.Material).ThenInclude(x => x.BoxPosition).
                                  ThenInclude(x => x.TheBoxGrid).ThenInclude(x => x.TheBox).Where(x => x.OrderNo == InPut.Symbol).ToListAsync();
                List<PutOutOrder> putOutOrders = await PutOutOrder_res.GetListAsync(x => x.Symbol == InPut.Symbol);
                if (neetOutMaterials.Count == 0)
                {
                    return new ApiResponse($"请先分配再下架", false, null);
                }
                List<MaterialBase> materialBases = await context.materialBases.Include(x => x.BoxPosition).ThenInclude(x => x.TheBoxGrid).
                                                  ThenInclude(x => x.TheBox).ThenInclude(x => x.WarehouseLine).Where(x => x.NeetOutMaterials.Any(y => y.OrderNo == InPut.Symbol)).ToListAsync();
                //查验任务中已存在的箱盒
                List<string> BoxCodes = materialBases.Select(x => x.BoxPosition.TheBoxGrid.TheBox.BoxCode).ToList();
                BoxCodes = BoxCodes.Distinct().ToList();
                BoxCodes = await context.taskOrders.Include(x => x.Box).Where(x => BoxCodes.Any(y => y == x.Box.BoxCode)).Select(x => x.Box.BoxCode).ToListAsync();
                if (BoxCodes.Count > 0)
                {
                    return new ApiResponse($"料盒{string.Join(",", BoxCodes)}已经分配到其他下架任务了", false, null);
                }

                //create taskerorder updateinlethouse
                InlethouseLine inlethouseLine = await Inlethouseline_res.FirstOrDefaultAsync(x => x.InlethouseLineCode == InPut.InlethouseCode);
                if (inlethouseLine == null)
                {
                    return new ApiResponse($"查询不到的出口", false, null);
                }
                materialBases = materialBases.DistinctBy(x => x.BoxPosition.TheBoxGrid.TheBox.BoxCode).ToList();
                List<TaskOrder> taskorders = new List<TaskOrder>();
                foreach (var item in materialBases)
                {
                    TaskOrder taskOrder = new TaskOrder();
                    taskOrder = taskOrder.AddTaskOrder("出库", item.BoxPosition.TheBoxGrid.TheBox, item.BoxPosition.TheBoxGrid.TheBox.WarehouseLine.WarehouseLineCode, InPut.InlethouseCode, InPut.Symbol, null, null,"未下发");
                    item.BoxPosition.TheBoxGrid.TheBox.TaskOrder = taskOrder;
                    inlethouseLine.IsOccupy = true;
                    foreach (var neetOutMaterial in neetOutMaterials)
                    {
                        if (neetOutMaterial.Material.BoxPosition.TheBoxGrid.TheBox.Id_Box == taskOrder.Box.Id_Box)
                        {
                            neetOutMaterial.TheTaskOrder = taskOrder;
                        }
                    }
                    await Box_res.UpdateAsync(item.BoxPosition.TheBoxGrid.TheBox);
                    taskorders.Add(taskOrder);
                }
                //update PutOutOrder
                putOutOrders.ForEach(x =>
                {
                    x.State = "已分配下架";
                });

                await PutOutOrder_res.UpdateManyAsync(putOutOrders);
                await NeetOutMaterial_res.UpdateManyAsync(neetOutMaterials);
                await TaskOrder_res.InsertManyAsync(taskorders);
                await MaterialBase_res.UpdateManyAsync(materialBases);
                await Inlethouseline_res.UpdateAsync(inlethouseLine);
                return new ApiResponse("料盒分配下架", true, null);
            }catch(Exception ex)
            {
                loginHelper.LoginAsync(InPut, "AllocationOrderAgvTask");
                return new ApiResponse("ERROR-AllocationOrderAgvTask", false, ex);
            }

        }//分配出库工单-添加agv

     
    }
}
